package com.atguigu.juc.day04.cf;

import com.atguigu.juc.day04.pool.Demo01MyPool;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;

public class Demo10AllOf {

    public static void main(String[] args) throws ExecutionException, InterruptedException {

        ExecutorService executorService = Demo01MyPool.getExecutorService();

        CompletableFuture<String> future01 = CompletableFuture.supplyAsync(() -> {

            try {
                System.out.println(Thread.currentThread().getName() + " 开始睡觉。");
                TimeUnit.SECONDS.sleep(2);
                System.out.println(Thread.currentThread().getName() + " 结束睡觉。");
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

            return "task 01 result";
        }, executorService);

        CompletableFuture<String> future02 = CompletableFuture.supplyAsync(() -> {

            try {
                System.out.println(Thread.currentThread().getName() + " 开始睡觉。");
                TimeUnit.SECONDS.sleep(4);
                System.out.println(Thread.currentThread().getName() + " 结束睡觉。");
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

            return "task 02 result";
        }, executorService);

        CompletableFuture<String> future03 = CompletableFuture.supplyAsync(() -> {

            try {
                System.out.println(Thread.currentThread().getName() + " 开始睡觉。");
                TimeUnit.SECONDS.sleep(6);
                System.out.println(Thread.currentThread().getName() + " 结束睡觉。");
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

            return "task 03 result";
        }, executorService);

        // 使用 allOf() 汇总上面三个任务
        // 汇总：涉及的所有任务都完成后，whenComplete()方法设定的回调函数执行
        CompletableFuture.allOf(future01, future02, future03).whenComplete((taskResult, throwable) -> {
            // 虽然设定了 taskResult 参数，但是没有拿到任何一个任务的结果
            System.out.println("whenComplete() taskResult = " + taskResult);
            System.out.println("whenComplete() throwable = " + throwable);
        });

        // 如果需要具体任务的结果就调用具体任务自己的 get() 方法
        String task01Result = future01.get();
        System.out.println("task01Result = " + task01Result);

        String task02Result = future02.get();
        System.out.println("task02Result = " + task02Result);

        String task03Result = future03.get();
        System.out.println("task03Result = " + task03Result);

    }

}
